<?php
declare (strict_types=1);

namespace app\services\worker;

use think\facade\Cache;
use think\facade\Event;
use think\facade\Snowflake;
use app\services\BaseServices;
use app\dao\worker\RepairWorkerDao;
use crmeb\exceptions\AdminException;
use app\services\worker\WorkerTokenServices;
use think\db\exception\{DataNotFoundException, DbException, ModelNotFoundException};


/**
 *
 * Class RepairWorkerServices
 * @package app\services\worker
 * @mixin RepairWorkerDao
 */
class RepairWorkerServices extends BaseServices
{

    /**
     * RepairWorkerServices constructor.
     * @param RepairWorkerDao $dao
     */
    public function __construct(RepairWorkerDao $dao)
    {
        $this->dao = $dao;
    }

    /**
     * 维修师傅注册登录
     * @param array $data
     * @param array $allowedDeviceTypes
     * @param string $ip
     * @return array
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function registerLogin(array $data, array $allowedDeviceTypes, string $ip)
    {
        /** @var RepairWorkerDao $getWorker */
        $getWorker = $this->dao->getOne(['mobile' => $data['mobile']]);

        $cache = Cache::get('tel' . $data['mobile']);
        if (!$cache) {
            throw new AdminException('验证码已失效！');
        }
        if ($data['code'] != $cache) {
            throw new AdminException('验证码不匹配！');
        }

        // 设备类型;mobile,android,iphone,ipad,web,pc,mac,wxapp,ios
        if (empty($data['device_type']) || !in_array($data['device_type'], $allowedDeviceTypes)) {
            throw new AdminException('请求错误,未知设备!');
        }

        $repair_worker_id = Snowflake::generate(); // 雪花算法 生成分布式用户ID

        $workerData = [
            'id' => $repair_worker_id,
            'user_type' => 1, // 师傅类型;1:普通师傅;2:高级师傅
            'mobile' => $data['mobile'],
            'make_code' => makeWorkerCode(), // 自动生成推广码
        ];

        $this->transaction(function () use ($repair_worker_id, $data, $workerData, $getWorker) {

            if (!$getWorker) {
                if (!$this->dao->save($workerData)) {
                    throw new AdminException('网络错误请稍后重试！');
                }
                $count = $this->dao->getCount(['mobile' => $data['mobile']]);
                if ($count > 1) {
                    throw new AdminException('网络错误请稍后重试！');
                }
            }

            return true;
        });
        Cache::delete('tel' . $data['mobile']); // 清除手机短信验证码缓存

        $token = md5(uniqid()) . md5(uniqid());
        $device_type = $data['device_type'];
        $findWorker = $this->dao->getOne(['mobile' => $data['mobile']]);
        $worker_info = $findWorker->toArray();

        $this->transaction(function () use ($findWorker, $data, $token, $ip, $device_type) {
            // 登录完成 记录token
            Event::trigger('worker.workerToken', [$findWorker['id'], $token, $device_type]);
            //登录日志消息队列
            event('worker.workerLoginLog', [$findWorker['id'], 1, $ip, $data['device_type']]);
            return true;
        });

        return compact('token', 'device_type', 'worker_info');
    }
}
